﻿using System;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Windows.Forms;
using LDriver;
using LDriver.Protocols;
using LDriver.Providers;
using System.IO.Ports;
using LModels;
using LModels.Proxy;
using Models;
using Models.Collections;

namespace LClient
{
    public partial class frmLidar : Form
    {

        private LidarSettings lidarSettings;
        private Workspace actualWorkspace;

        // Variabili pubbliche per l'inizializzazione
        private CommunicationManager cm;
        private ICommunicationProtocol prot;
        private ICommunicationProvider prov;

        BackgroundWorker bwSurveys = new BackgroundWorker();

        
        public frmLidar()
        {

            InitializeComponent();

            label1.Text = this.Text;


            AppStaticObjects.PM.AddProxy("lidarDB", new Proxy());

            ucVisualizer.ResizeUC();

            // Carico la TreeView
            //InitializeTreeView();
        }


        //private void InitializeTreeView()
        //{
        //    treeViewWorkspaces.Nodes.Clear();

        //    var rootNodeList = new FactoryCollection<WorkspaceCollection>(AppStaticObjects.PM.GetProxy("lidarDB")).List("List", null);

        //    foreach (Workspace w in rootNodeList)
        //        treeViewWorkspaces.Nodes.Add(new TreeNode((((Workspace)new Factory<Workspace>(AppStaticObjects.PM.GetProxy("lidarDB")).Load(w.ID)).Date.ToShortDateString())));

        //    foreach (Workspace w in rootNodeList)
        //    {
        //        TreeNode rootnode = treeViewWorkspaces.Nodes.OfType<TreeNode>().FirstOrDefault(node => node.Text.Equals(w.Date.ToShortDateString()));
        //        if (rootnode != null)
        //            rootnode.Nodes.Add(new TreeNode(string.Format("{0}-{1}", w.Description, w.Date)) { Tag = w });
        //    }

        //}

       
        // Inizializzazione del CommunicationManager.
        // Vengono impostate le informazioni relative al Provider (USB, RS232, ...)
        // ed al protocollo (Lidar, ...)
        private bool InitializePort()
        {
            if (lidarSettings == null)
            {
                MessageBox.Show("Impostare i parametri di connessione nel menu File -> Lidar Settings");
                return false;
            }

            prov = new RS232(lidarSettings.Port, lidarSettings.BaudRate, lidarSettings.Parity);

            prot = new LidarProtocol();
            prot.Initialize();

            cm = new CommunicationManager(prov, prot);

            bwSurveys = new BackgroundWorker();
            bwSurveys.WorkerSupportsCancellation = true;

            bwSurveys.DoWork += new DoWorkEventHandler(bwSurveys_DoWork);
            bwSurveys.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bwSurveys_RunWorkerCompleted);

            return true;

        }

        //// Il comando START
        ////private void btnStart_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
        //private void toolStripBtnRecording_Click(object sender, EventArgs e)
        //{

        //    // check Existing actualWorkspace
        //    if (actualWorkspace == null)
        //    {
        //        MessageBox.Show("Please select a Workspace from \"Workspaces Treeview\" or create new one", "",
        //            MessageBoxButtons.OK, MessageBoxIcon.Information);
        //    }
        //    else
        //    {
        //        try
        //        {
        //            InitializePort();

        //            // Imposto le dimensioni del ucVisualizer dedicato al Lidar
        //            ucVisualizer.ResizeUC();//ucVisualizer.Width, ucVisualizer.Height);

        //            // Invio al CommunicationManager il comando di START presente nel
        //            // protocollo
        //            cm.SendCommand(cm.GetCommand("START"));

        //            if (bwSurveys.IsBusy != true) bwSurveys.RunWorkerAsync();

        //            toolStripBtnRecording.Enabled = false;
        //            toolStripBtnStop.Enabled = true;

        //        }
        //        catch (Exception ex)
        //        {
        //            MessageBox.Show(ex.Message, "", MessageBoxButtons.OK, MessageBoxIcon.Error);
        //        }

        //    }

        //}

        //// Il comando STOP
        ////private void btnStop_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
        //private void toolStripBtnStop_Click(object sender, EventArgs e)
        //{

        //    // Invio al CommunicationManager il comando di STOP presente nel
        //    // protocollo
        //    try
        //    {
        //        cm.CancelWorker();
        //        cm.SendCommand(cm.GetCommand("STOP"));

        //        if (bwSurveys.WorkerSupportsCancellation == true) bwSurveys.CancelAsync();

        //        toolStripBtnRecording.Enabled = true;
        //        toolStripBtnStop.Enabled = false;
        //    }
        //    catch (Exception ex)
        //    {
        //       MessageBox.Show("Unable to send Stop command " + ex.Message);
        //    }

        //    if (MessageBox.Show("Do you want to save the surveys?", "", MessageBoxButtons.YesNo) == DialogResult.Yes)
        //    {

        //        //actualWorkspace.Recordings.SaveAndAddSurveys(cm.Surveys);

        //    }

        //}
        //int fatti = 0;

        private void bwSurveys_DoWork(object sender, DoWorkEventArgs e)
        {
            actualWorkspace = new Factory<Workspace>(AppStaticObjects.PM.GetProxy("lidarDB")).New() as Workspace;
            if (actualWorkspace != null)
            {
                actualWorkspace.Recordings.Add(
                    new Factory<Recording>(AppStaticObjects.PM.GetProxy("lidarDB")).New() as Recording);
                ((Recording) actualWorkspace.Recordings[0]).Save();
            }


            while (true)
            {

                // Verifico se è stata richiesta una interruzione delle attività
                if (bwSurveys.CancellationPending == true)
                {
                    this.Invoke((MethodInvoker) delegate
                                                {
                                                    //statusStrip.Text = "Task Canceled";
                                                    //MessageBox.Show("worker.CancellationPending");
                                                });
                    e.Cancel = true;
                    break;

                }
                else
                {

                    // textBox2.Text = "bwMeasurements attivo";
                    // toolStripStatusBackGroundWorker.Text = cm.Buffer.Count.ToString();
                    // LidarSurvey s = cm.FirstSurvey;
                    if (cm.FirstSurvey != null)
                    {
                        // Procedo alla visualizzazione dei dati
                        ucVisualizer.AddPoint(cm.FirstSurvey);

                        if (actualWorkspace != null)
                        {
                            if (((Recording)actualWorkspace.Recordings[0]).RecordingSurveys==null)
                                ((Recording)actualWorkspace.Recordings[0]).RecordingSurveys = new SurveysCollection();
                            
                            ((Recording) actualWorkspace.Recordings[0]).RecordingSurveys.Add(new Survey(cm.FirstSurvey,((Recording) actualWorkspace.Recordings[0]).IDRecordings));
                        }
                       
                    }


                    // Eseguita l'elaborazione della misurazione la elimino
                    cm.RemoveSurvey(cm.FirstSurvey);
                    
                }

            }

        }

        private void bwSurveys_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            //if ((e.Cancelled == true))
                //statusStrip.Text = "Canceled!";
           // else if (e.Error != null)
                //statusStrip.Text = "Error: " + e.Error.Message;
            //else
                //statusStrip.Text = "Done!";
            if (((Recording)actualWorkspace.Recordings[0]).RecordingSurveys != null && ((Recording)actualWorkspace.Recordings[0]).RecordingSurveys.Count > 0 &&
                MessageBox.Show("Vuoi salvare le rilevazioni in memoria?", "", MessageBoxButtons.YesNo) ==
                DialogResult.Yes)
            {
                ((Recording)actualWorkspace.Recordings[0]).SaveSurvey();
            }
            
        }

        private void frmLidar_Resize(object sender, EventArgs e)
        {

            // Efettuando il resize vado a ridisegnare il contenuto
            // dell'ucVisualizer dedicato al Lidar
            ucVisualizer.ResizeUC();//ucVisualizer.Width, ucVisualizer.Height);

        }




        //private void lidarConnectionToolStripMenuItem_Click(object sender, EventArgs e)
        //{
        //    frmLidarSettings frm = new frmLidarSettings(lidarSettings);
        //    if (frm.ShowDialog() == DialogResult.OK)
        //    {
        //        lidarSettings = frm.ls;

        //        toolStripBtnRecording.Enabled = true;
        //        toolStripBtnStop.Enabled = false;

        //        InitializeTreeView();
        //    }

        //}
        
        //private void mapperToolStripMenuItem_Click(object sender, EventArgs e)
        //{
        //    //using (frmMapper map = new frmMapper())
        //    //{
        //    //    map.ShowDialog();
        //    //}
        //}


        //#region Treeview

        //// Workspace Selection
        //private void useThisWorkspaceToolStripMenuItem_Click(object sender, EventArgs e)
        //{
        //    if (contextMenuStrip1.Tag != null)
        //    {
        //        var w = contextMenuStrip1.Tag as Workspace;
        //        if (w != null)
        //            actualWorkspace = w;
        //    }
        //}


        //private void rinominaToolStripMenuItem_Click(object sender, EventArgs e)
        //{
        //    if (contextMenuStrip1.Tag != null)
        //    {
        //        var w = contextMenuStrip1.Tag as Workspace;
        //        frmWorkspaceDetails frmDetails = new frmWorkspaceDetails(w);
        //        if (frmDetails.ShowDialog() == DialogResult.OK)
        //        {
        //            InitializeTreeView();
        //        }
        //    }

        //}


        //private void esportaToolStripMenuItem_Click(object sender, EventArgs e)
        //{
        //    using (SaveFileDialog sfd = new SaveFileDialog() {DefaultExt = ".scr", CheckPathExists = true})
        //    {
        //        if (sfd.ShowDialog() == DialogResult.OK)
        //        {
        //            if (!string.IsNullOrEmpty(sfd.FileName))
        //            {
                        
        //            }

        //        }

        //    }

        //}

        //private void eliminaToolStripMenuItem_Click(object sender, EventArgs e)
        //{
        //    if (
        //        MessageBox.Show("Sei sicuro di voler cancellare l'intero workspace?", "Lidar", MessageBoxButtons.YesNo) ==
        //        DialogResult.Yes)
        //    {
        //        if (contextMenuStrip1.Tag != null)
        //        {
        //            var w = contextMenuStrip1.Tag as Workspace;
        //            w.Delete();

        //            InitializeTreeView();
        //        }
        //    }
        //}

        //private void treeView1_MouseClick(object sender, MouseEventArgs e)
        //{
        //    contextMenuStrip1.Tag = null;

        //    if (e.Button == MouseButtons.Right)
        //    {
        //        TreeViewHitTestInfo info = treeViewWorkspaces.HitTest(e.X, e.Y);
        //        if (info != null && info.Node != null)
        //        {
        //            treeViewWorkspaces.SelectedNode = info.Node;

        //            if (info.Node.Tag != null)
        //            {
        //                contextMenuStrip1.Tag = info.Node.Tag;
        //                contextMenuStrip1.Show(treeViewWorkspaces, e.X, e.Y);
        //            }
        //        }
        //    }
        //}

        //#endregion

        private void btnStart_Click(object sender, EventArgs e)
        {
            try
            {
                InitializePort();

                // Imposto le dimensioni del ucVisualizer dedicato al Lidar
                ucVisualizer.ResizeUC();//ucVisualizer.Width, ucVisualizer.Height);

                // Invio al CommunicationManager il comando di START presente nel
                // protocollo
                cm.SendCommand(cm.GetCommand("START"));

                if (bwSurveys.IsBusy != true) bwSurveys.RunWorkerAsync();

                // Layout
                btnStart.Enabled = false;
                btnStop.Enabled = true;
                btnConfig.Enabled = false;

            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        private void btnStop_Click(object sender, EventArgs e)
        {
            try
            {
                cm.CancelWorker();
                cm.SendCommand(cm.GetCommand("STOP"));

                if (bwSurveys.WorkerSupportsCancellation == true) bwSurveys.CancelAsync();

                // Layout
                btnStart.Enabled = true;
                btnStop.Enabled = false;
                btnConfig.Enabled = true;

            }
            catch (Exception ex)
            {
                MessageBox.Show("Unable to send Stop command " + ex.Message);
            }
        }

        private void btnConfig_Click(object sender, EventArgs e)
        {
            frmLidarSettings frm = new frmLidarSettings(lidarSettings);
            if (frm.ShowDialog() == DialogResult.OK)
            {
                lidarSettings = frm.ls;

                //toolStripBtnRecording.Enabled = true;
                //toolStripBtnStop.Enabled = false;

                //InitializeTreeView();
            }
        }

        private void ucVisualizer_Load(object sender, EventArgs e)
        {

        }
        
    }

}
